/*
 * libedb.h - EnCluster Base DB Client part interfaces
 * Clunix, glory@clunix.com, yjlee@clunix.com, 2001.7.18.
 * Clunix, cezanne@clunix.com, 2005.3
 *
 * Copyright (c) 2001,2002,2003 by Clunix Inc. All Rights Reserved.
 */

#ifndef _LIBEDB_H_
#define _LIBEDB_H_

#include "libsr.h"
#include "libebc.h"
#include "edb_type.h"

typedef	int	edb_err_t;

typedef enum {
	EDB_FIELD_NAME	= 0,
	EDB_FIELD_TYPE,
	EDB_FIELD_VAL,
	EDB_FIELD_OWNER,
	EDB_FIELD_USER,
	EDB_FIELD_GROUP,
	EDB_FIELD_PERM,
	EDB_FIELD_ATTR_UPDATE,
	EDB_FIELD_ATTR_FETCH,
	EDB_FIELD_ATTR_SYSTEM,
	EDB_FIELD_REACTOR
} edb_field_t;

typedef enum {
	EDB_FILEOPT_RECUR = 1,
	EDB_FILEOPT_FORCE = 2,
} edb_fileopt_t;

typedef int	edb_file_id_t;

#define EDB_OK				0
#define ERR_EDB_GENERAL			1
#define ERR_EDB_VERSION			2
#define ERR_EDB_INVALKEY		3
#define ERR_EDB_AUTH			4
#define ERR_EDB_INVALIDARG		5
#define ERR_EDB_TIMEOUT			6
#define ERR_EDB_CONNLOST		7
#define ERR_EDB_CONN			8
#define ERR_EDB_LNP			9
#define ERR_EDB_NOTEXIST		10
#define ERR_EDB_EXIST			11
#define ERR_EDB_WRONGASRV		12
#define ERR_EDB_INVALIDLNP		13
#define ERR_EDB_WRONGCNP		14
#define ERR_EDB_INVALIDCMD		15
#define ERR_EDB_WRONGLNP		16
#define ERR_EDB_WRONGEDEXPR		17
#define ERR_EDB_MIXEDTYPE		18
#define ERR_EDB_BUSY			19
#define ERR_EDB_WRONGTARGET		20
#define ERR_EDB_NOTALLOWED		21
#define ERR_EDB_NULLNAME		22
#define ERR_EDB_WRONGMODE		23
#define ERR_EDB_WRONGFIELD		24
#define ERR_EDB_NOTMASTER		25
#define ERR_EDB_WRONGSRT		26
#define ERR_EDB_NOTSUPPORTED		27
#define ERR_EDB_NOTCHANGED		28
#define ERR_EDB_CANCELLED		29
#define ERR_EDB_MASTERFAILED		30

#define EDB_ONE			0x0001
#define EDB_CHILD		0x0002
#define EDB_RECUR		0x0004
#define EDB_NO_DEREF		0x0008 
#define EDB_NOT_THIS		0x0010
#define EDB_OPT_CHGDIR		0x0100

#ifdef __cplusplus
extern "C" {
#endif

typedef struct _edb_t edb_t;   /* defined in edb private header */

ECM_EXPIMP ecm_uint32	edb_timeout;

/* connect & close */
edb_err_t edb_connect(const char *servaddr, ecm_uint16, const char *user, const char *passwd, edb_t **);
edb_err_t edb_connect_node(ecm_ebc_t ecm_ebc, ebc_ndid_t ndid, const char *user, const char *passwd, edb_t **);
edb_err_t edb_connect_master(const char *servaddr, ecm_uint16, const char *user, const char *passwd, edb_t **);
edb_err_t edb_connect_session(const char *servaddr, ecm_uint16, const char *user, const char *sessionid, edb_t **);
edb_err_t edb_reconnect(edb_t *e);
void edb_close(edb_t *e);

ECMBOOL edb_is_master(edb_t *e);

edb_err_t edb_cd(edb_t *e, const char *LNP, const char *EDExpr, char **pcwd);
edb_err_t edb_cd_free(edb_t *e, char *LNP, char *EDExpr, char **pcwd);

edb_err_t edb_scan_asrv(edb_t *e, srt_t srt, char *asrv, sr_t **psr);

/* create */
edb_err_t edb_create(edb_t *e, const char *LNP, srt_t srt, sr_val_t val);
edb_err_t edb_create_sr(edb_t *e, const char *LNP, const char *EDExpr, sr_t *sr);

#define edb_create_int(e, name, type, ival)  \
	edb_create(e, name, type, sr_val_int(ival)) 
#define edb_create_ll(e, name, type, lval)   \
	edb_create(e, name, type, sr_val_ll(lval))
#define edb_create_dbl(e, name, type, dval)  \
	edb_create(e, name, type, sr_val_dbl(dval))
#define edb_create_str(e, name, type, str)   \
	edb_create(e, name, type, sr_val_str(str))
#define edb_create_oct(e, name, type, size, data)  \
	edb_create(e, name, type, sr_val_oct(size, data))
#define edb_create_dir(e, name)  \
	edb_create(e, name, ST_DIR, SR_VAL_NULL)
#define edb_create_link(e, name, link)  \
	edb_create(e, name, ST_EDB_LINK, sr_val_str(link))

edb_err_t edb_get_modinfos(edb_t *e, sr_t **psr_ret);

/* typename */
edb_err_t edb_get_type_name(edb_t *e, srt_t srt, char **psrt_str);
edb_err_t edb_get_inherited_types(edb_t *e, srt_t srt, sr_t **psr_ret);
edb_err_t edb_search_srt(edb_t *e, const char *srtstr, srt_t *psrt);

char *edb_get_sr_asrv(edb_t *e, sr_t *sr_req);

/* get; cnp: conditional name pattern */
edb_err_t edb_get_field(edb_t *e, edb_field_t field, const char *LNP, const char *EDExpr, int opt, sr_t **psr_res);
sr_t *edb_get_field_1(edb_t *e, edb_field_t field, const char *LNP, const char *EDExpr, int opt);
edb_err_t edb_get_field_free(edb_t *e, edb_field_t field, char *LNP, char *EDExpr, int opt, sr_t **psr_res);
sr_t *edb_get_field_1_free(edb_t *e, edb_field_t field, char *LNP, char *EDExpr, int opt);

#define edb_get(e, LNP, EDExpr, opt, psr) \
		edb_get_field(e, EDB_FIELD_VAL, LNP, EDExpr, opt, psr)
#define edb_get_1(e, LNP, EDExpr, opt) \
		edb_get_field_1(e, EDB_FIELD_VAL, LNP, EDExpr, opt)
#define edb_get_free(e, LNP, EDExpr, opt, psr) \
		edb_get_field_free(e, EDB_FIELD_VAL, LNP, EDExpr, opt, psr)
#define edb_get_1_free(e, LNP, EDExpr, opt) \
		edb_get_field_1_free(e, EDB_FIELD_VAL, LNP, EDExpr, opt)

ecm_int32 edb_get_int(edb_t *ed, const char *LNP, const char *EDExpr, int opt);
ecm_int64 edb_get_ll(edb_t *ed, const char *LNP, const char *EDExpr, int opt);
char *edb_get_str(edb_t *ed, const char *LNP, const char *EDExpr, int opt);
ecm_double edb_get_dbl(edb_t *ed, const char *LNP, const char *EDExpr, int opt);
ECMBOOL edb_get_bool(edb_t *ed, const char *LNP, const char *EDExpr, int opt);

ecm_int32 edb_get_int_free(edb_t *ed, char *LNP, char *EDExpr, int opt);
ecm_int64 edb_get_ll_free(edb_t *ed, char *LNP, char *EDExpr, int opt);
char *edb_get_str_free(edb_t *ed, char *LNP, char *EDExpr, int opt);
ecm_double edb_get_dbl_free(edb_t *ed, char *LNP, char *EDExpr, int opt);
ECMBOOL edb_get_bool_free(edb_t *ed, char *LNP, char *EDExpr, int opt);

ECMBOOL edb_exist(edb_t *e, const char *LNP, const char *EDExpr);
ECMBOOL edb_exist_free(edb_t *e, char *LNP, char *EDExpr);

int edb_get_num_child(edb_t *e, char *format, ...);

int edb_set_field(edb_t *e, edb_field_t field, const char *LNP, const char *EDExpr, const char *asrv, int opt);

/* set by sr */
edb_err_t edb_set_field_sr(edb_t *e, edb_field_t edb_field, const char *LNP, const char *EDExpr, sr_t *sr, int opt);
edb_err_t edb_set_field_sr_free(edb_t *e, edb_field_t edb_field, char *LNP, char *EDExpr, sr_t *sr, int opt);

#define edb_set_sr(e, LNP, EDExpr, sr, opt)   \
	edb_set_field_sr(e, EDB_FIELD_VAL, LNP, EDExpr, sr, opt)
#define edb_set_sr_free(e, LNP, EDExpr, sr, opt)   \
	edb_set_field_sr_free(e, EDB_FIELD_VAL, LNP, EDExpr, sr, opt)

/* set values */
#define edb_set_int(e, LNP, EDExpr, ival)	\
        edb_set_sr(e, LNP, EDExpr, sr_create_int(ST_INT, ival), 0)
#define edb_set_ll(e, LNP, EDExpr, lval)	\
	edb_set_sr(e, LNP, EDExpr, sr_create_ll(ST_LL, lval), 0)
#define edb_set_str(e, LNP, EDExpr, str)	\
        edb_set_sr(e, LNP, EDExpr, sr_create_str(ST_STR, str), 0)
#define edb_set_dbl(e, LNP, EDExpr, dval)	\
	edb_set_sr(e, LNP, EDExpr, sr_create_dbl(ST_DBL, dval), 0)
#define edb_set_oct(e, LNP, EDExpr, size, data)	\
	edb_set_sr(e, LNP, EDExpr, sr_create_oct(ST_OCT, size, data), 0)
#define edb_set_bool(e, LNP, EDExpr, bval)	\
	edb_set_sr(e, LNP, EDExpr, sr_create_bool(ST_BOOL, bval), 0)

#define edb_set_int_free(e, LNP, EDExpr, ival)	\
        edb_set_sr_free(e, LNP, EDExpr, sr_create_int(ST_INT, ival), 0)
#define edb_set_ll_free(e, LNP, EDExpr, lval)	\
	edb_set_sr_free(e, LNP, edexpr, sr_create_ll(ST_LL, lval), 0)
#define edb_set_str_free(e, LNP, EDExpr, str)	\
        edb_set_sr_free(e, LNP, EDExpr, sr_create_str(ST_STR, str), 0)
#define edb_set_dbl_free(e, LNP, EDExpr, dval)	\
	edb_set_sr_free(e, LNP, EDExpr, sr_create_dbl(ST_DBL, dval), 0)
#define edb_set_oct_free(e, LNP, EDExpr, size, data)	\
	edb_set_sr_free(e, LNP, EDExpr, sr_create_oct(ST_OCT, size, data), 0)
#define edb_set_bool_free(e, LNP, EDExpr, bval)	\
	edb_set_sr_free(e, LNP, EDExpr, sr_create_bool(ST_BOOL, bval), 0)

/* del */
edb_err_t edb_del(edb_t *e, const char *LNP, const char *EDExpr, int opt);

/* EDB control */
edb_err_t edb_snapshot(edb_t *e);

edb_err_t edb_shutdown(edb_t *e, const char *LNP);

edb_err_t edb_file_open(edb_t *e, ebc_ndid_t ndid, const char *vpath, edb_file_id_t *pfid, int flags);
edb_err_t edb_file_ropen(edb_t *e, ebc_ndid_t ndid, const char *vpath, edb_file_id_t *pfid, ecm_uint64 startoff);
edb_err_t edb_file_close(edb_t *e, edb_file_id_t fid, ECMBOOL done);
edb_err_t edb_file_read(edb_t *e, edb_file_id_t fid, ecm_uint8 *buf, ecm_size_t *psize);
edb_err_t edb_file_write(edb_t *e, edb_file_id_t fid, ecm_uint8 *buf, ecm_size_t size);

edb_err_t edb_file_upload(edb_t *e, const char *src_path,
			  ebc_ndid_t dst_ndid, const char *dst_path, edb_fileopt_t opt);
edb_err_t edb_file_download(edb_t *e, const char *dst_path,
			    ebc_ndid_t src_ndid, const char *src_path, edb_fileopt_t opt);

edb_err_t edb_file_exist(edb_t *e, ebc_ndid_t ndid, const char *vpath);
edb_err_t edb_file_copy(edb_t *e,
			ebc_ndid_t src_ndid, const char *src_path,
			ebc_ndid_t dst_ndid, const char *dst_path, edb_fileopt_t opt);
edb_err_t edb_file_remove(edb_t *e, ebc_ndid_t ndid, const char *path, edb_fileopt_t opt);
edb_err_t edb_file_mkdir(edb_t *e, ebc_ndid_t ndid, const char *vpath, edb_fileopt_t opt);

edb_err_t edb_auth_user(edb_t *e, const char *username, const char *passwd, char **psessionid);

edb_err_t edb_exec(edb_t *e, const char *EDExpr, sr_t **psr_res, ecm_uint32 nargs, ...);
edb_err_t edb_exec_process(edb_t *e, ebc_ndid_t ndid, sr_exectx_t *pexectx);

edb_err_t edb_elect_master(edb_t *e);

/* Echo: TODO */
int edb_echo(edb_t *e, char *msg);

/* XE operations */
edb_err_t edb_xecreate(edb_t *e, const char *LNP, const char *EDExpr, const char *srname, const char *srtstr, sr_t **sr_pres);
edb_err_t edb_xedelete(edb_t *e, const char *LNP, const char *EDExpr, ECMBOOL force, sr_t **sr_pres);

typedef void (*edb_pathmoncb_t)(const char *LNP, ecm_ptr_t ctx);

edb_err_t edb_add_pathmon(edb_t *e, const char *LNP, edb_pathmoncb_t moncb, ecm_ptr_t ctx, ecm_ptr_t *pkey);
edb_err_t edb_del_pathmon(edb_t *e, ecm_ptr_t key);

#ifdef __cplusplus
}
#endif

#endif  /* _LIBEDB_H_ */

